package com.year.shiyi.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.year.shiyi.common.exception.BusinessException;
import com.year.shiyi.common.utils.Constant;
import com.year.shiyi.common.utils.PageUtils;
import com.year.shiyi.common.utils.Query;
import com.year.shiyi.entity.mybatis.SysMenuEntity;
import com.year.shiyi.entity.mybatis.SysRoleEntity;
import com.year.shiyi.entity.mybatis.SysRoleMenuEntity;
import com.year.shiyi.mapper.SysRoleMapper;
import com.year.shiyi.service.SysMenuService;
import com.year.shiyi.service.SysRoleMenuService;
import com.year.shiyi.service.SysRoleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.ibatis.annotations.Update;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.constraints.NotBlank;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 角色 服务实现类
 * </p>
 *
 * @author shiyi
 * @since 2021-02-02
 */
@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRoleEntity> implements SysRoleService {


    @Autowired
    private SysRoleMenuService sysRoleMenuService;
    @Autowired
    private SysMenuService sysMenuService;

    @Override
    public List<SysRoleEntity> listRoleByUserId(Long userId) {
        return this.baseMapper.listRoleByUserId(userId);
    }

    @Override
    public PageUtils queryPage(Map<String, Object> param, Long userId) {
        List<SysRoleEntity> entities = this.listRoleByUserId(userId);
        Optional<String> first = entities.stream().map(SysRoleEntity::getRoleName).filter(x -> x.equals(Constant.SUPER_ADMIN)).findFirst();
        if (!first.isPresent()) {
            param.put("createUserId", userId);
            param.put("status", Constant.CommonStatus.NORMAL);
        }
        IPage<SysRoleEntity> page = this.page(new Query<SysRoleEntity>().getPage(param, true),
                new QueryWrapper<SysRoleEntity>().eq("status", Constant.CommonStatus.NORMAL.getValue()));
        return new PageUtils(page);
    }

    @Override
    public List<SysRoleEntity> select(Map<String, Object> param, Long userId) {
        List<SysRoleEntity> entities = this.listRoleByUserId(userId);
        Optional<String> first = entities.stream().map(SysRoleEntity::getRoleName).filter(x -> x.equals(Constant.SUPER_ADMIN)).findFirst();
        if (!first.isPresent()) {
            param.put("createUserId", userId);
            param.put("status", Constant.CommonStatus.NORMAL);
        }
       return this.listByMap(param);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveRole(SysRoleEntity role) {
        role.setCreateTime(new Date());
        role.setUpdateTime(new Date());
        // 检查角色是否越权
        checkPrems(role);
        this.save(role);
        return sysRoleMenuService.saveOrUpdate(role.getRoleId(), role.getMenuIdList());
    }

    @Override
    public boolean update(SysRoleEntity role) {
        role.setUpdateTime(new Date());
        checkPrems(role);
        this.updateById(role);
        return sysRoleMenuService.saveOrUpdate(role.getRoleId(), role.getMenuIdList());
    }

    @Override
    public boolean disable(Long roleId, Long userId, String action) {
        SysRoleEntity role = new SysRoleEntity();
        role.setUpdateTime(new Date());
        role.setCreateUserId(userId);
        role.setRoleId(roleId);
        role.setStatus("up".equals(action) ? Constant.CommonStatus.NORMAL.getValue() : Constant.CommonStatus.DISABLE.getValue());
        checkPrems(role);
        return this.update(new UpdateWrapper<SysRoleEntity>()
                .set("status", role.getStatus())
                .eq("role_id", role.getRoleId()));
    }

    @Override
    public boolean deleteBatch(Long[] roleIds) {
        // 删除角色
        return this.update(new UpdateWrapper<SysRoleEntity>().in("role_id").set("status", Constant.CommonStatus.DISABLE.getValue()));
//        this.removeByIds(Arrays.asList(roleIds));
//        sysRoleMenuService.remove(new UpdateWrapper<SysRoleMenuEntity>().in("role_id", Arrays.asList(roleIds)));
//        return true;
    }

    private void checkPrems(SysRoleEntity role) {
        Long userId = role.getCreateUserId();
        List<Long> menuIds = new ArrayList<>();
        Optional<String> first = this.listRoleByUserId(userId).stream().map(SysRoleEntity::getRoleName).filter(x -> x.equals(Constant.SUPER_ADMIN)).findFirst();
        if (first.isPresent()) {
            return;
        }
        menuIds = sysMenuService.listMenu(userId).stream().map(SysMenuEntity::getMenuId).collect(Collectors.toList());
        if (!menuIds.containsAll(role.getMenuIdList())) {
            throw new BusinessException("新增角色权限，已超过您的权限范围");
        }
    }
}
